package club.kynb.mall.application.flow.user;

import club.kynb.mall.application.constant.AuthConst;
import club.kynb.mall.application.context.AuthenticationContext;
import club.kynb.mall.application.context.MallUserContext;
import club.kynb.mall.application.model.model.command.AuthenticationCommand;
import club.kynb.mall.application.model.model.dto.TokenDTO;
import club.kynb.mall.application.model.model.event.AuthSuccessEvent;
import club.kynb.mall.application.repository.AuthRepository;
import club.kynb.mall.user.model.dto.UserDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.event.publish.EventBus;
import org.pizza.pattern.filter.Filter;
import org.pizza.pattern.filter.FilterInvoker;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author kynb_club@163.com
 * @since 2020/12/18 1:48 下午
 * 认证成功过滤器
 */
@Slf4j
@Component
@AllArgsConstructor
public class AuthSuccessFilter implements Filter<AuthenticationContext> {
    private final AuthRepository authRepository;
    private final EventBus eventBus;

    @Override
    public void doFilter(AuthenticationContext authenticationContext, FilterInvoker<AuthenticationContext> filterInvoker) {
        log.info("认证成功过滤器 start");
        TokenDTO token = authenticationContext.getToken();
        final UserDTO user = authenticationContext.getUser();
        final MallUserContext mallUserContext = new MallUserContext();
        mallUserContext.setUserDTO(user);
        mallUserContext.setTokenDTO(token);
        //保存token
        authRepository.saveContext(getKey(token.getAccessToken()), mallUserContext);
        //登录成功事件发送
        this.fireAuthSuccessEvent(authenticationContext, token);
        log.info("认证成功过滤器 end");
        filterInvoker.invoke(authenticationContext);
    }

    private void fireAuthSuccessEvent(AuthenticationContext authenticationContext, TokenDTO token) {
        AuthenticationCommand command = authenticationContext.getAuthenticationCommand();
        UserDTO user = authenticationContext.getUser();
        //发送认证成功事件
        eventBus.publishEvent(AuthSuccessEvent.builder()
                .userId(user.getId())
                .clientIp(command.getClientIp())
                .clientType(command.getClientType())
                .actionType(1)
                .token(token.getAccessToken())
                .tokenExpireTime(new Date(System.currentTimeMillis() + token.getTokenExpire() * 60 * 1000))
                .build());
    }

    private String getKey(String token) {
        return String.format("%s:%s", AuthConst.TOKEN_PREFIX, token);
    }

}
